package com.songlanyun.common.kqUtils;

import java.math.BigDecimal;
import java.net.SocketTimeoutException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.net.ssl.SSLContext;

import org.apache.commons.io.IOUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.http.HttpStatus;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ConnectTimeoutException;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;

import com.alibaba.fastjson.JSON;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

@Component
public class InitReFund {
    public static Log logger = LogFactory.getLog(InitReFund.class);
    public static QuickPayProperties quickPayProperties;
    private static final String appScheme = "billdemo";   //支付宝支付填写参数
    private static final String appName = "惠选中亿";   //APP名称

    @Autowired
    public InitReFund(QuickPayProperties properties) {
        quickPayProperties = properties;
    }

    /**
     * gateWay方式的退款
     *
     * @param amount 退款金额
     * @param orderCode 待退款的订单编号
     * @param origIdBizCtrl 订单付款成功后快钱返回的交易控制编号
     * @param clinetIp 调用方服务器的IP
     * @param goodsDetails 商品详情
     *
     * @return 返回一个Map实例。当退款成功时Map实例包含快钱返回的若干数据，否则Map实例包含了一个叫做“error”的key其值是程序运行中出现的异常实例。
     *
     * @since 2024-04-09
     * @author 王熙伟(18640387442)
     */
    public static Map<String, Object> gateWayInitReFund(BigDecimal amount, String orderCode, String origIdBizCtrl,
                                                        String clinetIp, String goodsDetails) {
        Map<String, Object> request = new HashMap<String, Object>();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        //会员编号
        request.put("memberCode", quickPayProperties.getMemberCode());
        //商户编号
        request.put("merchantId", quickPayProperties.getMerchantId());
        //商户对应的终端编号
        request.put("terminalId", quickPayProperties.getTerminalCode());
        //交易类型:RFD
        request.put("txnType", "RFD");
        //商户订单号
        request.put("externalTraceNo", orderCode);
        //原快钱交易控制编号
        request.put("origIdBizCtrl", origIdBizCtrl);
        //请求时间		格式为:yyyyMMddHHmmss
        request.put("requestTime", sdf.format(new Date()));
        //退货金额(元)
        request.put("amt", amount);
        //请求方IP地址
        request.put("clientIp", clinetIp);
        //request.put("sharingFlag","1");    /* 分账参数 */
        //request.put("sharingData","2^HAT_10012932671^0.01^test1|2^HAT_10012934672^0.01^test2"); /* 分账参数 */
        Sign sign = new Sign();
        sign.init(quickPayProperties);
        sign.createPrivateKey();
        String s = sign.doSign(request);
        request.put("sign", s);
        sign.createPublicKey();

        // 输出请求报文的内容
        logger.info("退款报文的请求参数:" + JSON.toJSONString(request));
        //测试环境下提交地址
        //String reqUrl = "https://sandbox.99bill.com/sdk-gateway/sdkGatewayService";
        //生产环境下提交地址
        String reqUrl = "https://picsdk.99bill.com/sdk-gateway/sdkGatewayService";

        String response = "";
        Map<String, Object> resultMap = new HashMap<String, Object>();
        try {
            response = HttpUtil.doPostJsonRequestByHttps(JSON.toJSONString(request), reqUrl, 3000, 80000);
            resultMap = JSON.parseObject(response, Map.class);
            logger.info("快钱返回的JSON对象===" + resultMap);
            logger.info("快钱返回的Response对象===" + response);
            sign.verificate(String.valueOf(resultMap.get("sign")), resultMap);
            return resultMap;
        } catch (Exception e) {
            logger.error("快钱退款异常：\n" + e.getStackTrace() + "\nInitReFund.java\n" + e.getMessage());
            resultMap.put("error", e);
            return resultMap;
        }
    }

    /**
     * HTTP请求（POST方式）的退款
     *
     * @param requestObject
     * @param url
     * @param connectTimeout
     * @param socketTimeOut
     * @return
     * @throws Exception
     */
    public static String postHttpRequest(Object requestObject, String url, int connectTimeout, int socketTimeOut)
            throws Exception {
        CloseableHttpResponse response = null;
        try {
            String reqeustString = "{}";
            if (requestObject != null) {
                reqeustString = JSON.toJSONString(requestObject);
            }
            logger.info("[send to gateWay service] message : " + reqeustString);

            CloseableHttpClient httpclient = HttpClients.createDefault();

            HttpPost httpPost = new HttpPost(url);
            SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
            sslContext.init(null, null, null);
            SSLContext.setDefault(sslContext);

            StringEntity sEntity = new StringEntity(reqeustString, "UTF-8");
            sEntity.setContentType("application/json");
            //
            RequestConfig requestConfig = RequestConfig.custom().setConnectionRequestTimeout(connectTimeout)
                    .setConnectTimeout(connectTimeout).setSocketTimeout(socketTimeOut).build();
            httpPost.setConfig(requestConfig);
            httpPost.setEntity(sEntity);
            response = httpclient.execute(httpPost);
            // get http status code
            int resStatu = response.getStatusLine().getStatusCode();
            String responseString = null;
            if (resStatu == HttpStatus.SC_OK) {
                responseString = IOUtils.toString(response.getEntity().getContent(), "UTF-8");
            } else {
                logger.error("rquestUrl:" + url + ", the connection is error,statusCode=" + resStatu);
                throw new Exception(url + ",the statusCode is " + resStatu);
            }
            return responseString;
        } catch (ConnectTimeoutException e) {
            logger.error("http post connection timeout", e);
            throw e;
        } catch (SocketTimeoutException e) {
            logger.error("http post socket timeout", e);
            throw e;
        } catch (Exception e) {
            logger.error("http post throw Exception", e);
            throw e;
        } finally {
            if (response != null) {
                try {
                    EntityUtils.consume(response.getEntity());
                    response.close();
                } catch (Exception e) {
                    logger.error("http connection closed error", e);
                }
            }
        }
    }

}
